package masterjava.common.configuration.setting;

import masterjava.common.property.IPropertyListener;
import masterjava.common.property.Property;

import java.net.InetAddress;
import java.net.URL;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * MasterJava.ru
 * <p/>
 * User: GKislin
 * Date: 31-Jan-2011
 */
public class UrlsSetting extends MapSetting<URL> {
    static final String PROPERTY_FILE_NAME = "url.properties";

    // find in url ${hostName}
    // Host templates must begin with letter ([a-zA-Z]) and contains any world cheracter (\w) or '.'
    static final Pattern HOST_PATTERN = Pattern.compile("\\x24\\x7B([a-zA-Z][\\w\\x2E].*?)\\x7D");
    private static HostsSetting HOSTS_SETTING = HostsSetting.get();

    public UrlsSetting() {
        super(PROPERTY_FILE_NAME);
        initMap(URL.class);
    }


    @Override
    protected Property<URL> createPropItem(String key, Class<URL> clazz) {
        final Property<URL> urlProp = new Property<URL>(key, null, clazz, propStore) {

            // Replace host template in ULR
            @Override
            public URL toValue(String property) {
                Matcher matcher = HOST_PATTERN.matcher(property);
                if (matcher.find()) {
                    property = matcher.replaceFirst(HOSTS_SETTING.getAsString(matcher.group()));
                }
                return super.toValue(property);
            }
        };

        // if  ULR is host templated: add to Host Property URL Property observer for change URL's host
        // Host property store already keep new value, as listener notify after update
        String value = propStore.getProperty(key);
        Matcher matcher = HOST_PATTERN.matcher(value);
        if (matcher.find()) {
            HOSTS_SETTING.get(matcher.group()).addListener(
                    new IPropertyListener<InetAddress>() {
                        @Override
                        public void update(Property<InetAddress> hostProp, InetAddress newValue) {
                            urlProp.reInitValue();
                        }
                    }
            );
        }
        return urlProp;
    }

    public static UrlsSetting get() {
        return get(PROPERTY_FILE_NAME, UrlsSetting.class);
    }
}
